import MySQLdb
import itertools
import time
class DB:
	__db = ''
	
	__cursor = ''

	__tbl = ""
	
	__primaryKey = "id"

	def __init__(self , tbl):
		self.__db = MySQLdb.connect(user="root" , db="newsbagcn" , passwd="dadipedia@mysql" , host="localhost")
		self.__cursor = self.__db.cursor()
		self.__tbl = tbl


	def setPrimaryKey(key):
		self.__primaryKey = key
	
	def getAll(self,sql):
		self.__cursor.execute(sql)
		results = []
		column_names =  [d[0] for d in self.__cursor.description]
		results = [dict(itertools.izip(column_names, row)) for row in self.__cursor]
		return results

	def getOne(self, sql):
		self.__cursor.execute(sql)
		results = []
		for row in self.__cursor:
			results.append(row[0])
		if len(results):
			return results[0]
		else:
			return null

	def execute(self,sql):
		self.__cursor.execute(sql)


	def insert(self,data):
		sql = ""
		cols = ""
		values = ""
		cols =  ",".join(data.keys())
		values = ",".join([ "'%s'" % s for s in [MySQLdb.escape_string ( str(s) ) for s in data.values()]])
		#for k in enumerate(data):
			#print k
			#cols += "%s , " % k
			#values += "%s , " % data[k]
		sql = "insert into %s ( %s ) values ( %s ) " % (self.__tbl , cols , values)
		self.execute(sql)
		return self.__cursor.lastrowid
	
	def update(self,data,expr):
		values =  ",".join(["=".join( (str(k) , "'%s'" %  str(data[k])) ) for k in data])
		sql = "UPDATE %s SET %s WHERE %s " %(self.__tbl , values , expr)
		self.execute(sql)
		return self.__cursor.rowcount

class R:
	usersLink = []
	
	leaders = []

	fans  = []

	db = '';
	def __init__(self):
		self.db = DB("nc_recommend")
		for row in self.db.getAll("SELECT user_id , news_id  , action_type FROM nc_actions"):
			if len(self.usersLink) <= row["user_id"]:
				self.usersLink.extend([set()] * (row["user_id"] - len(self.usersLink) + 1))
			#self.usersLink[row["user_id"]][row["news_id"]] = row["action_type"]
			if row["action_type"] == "digg":
				self.usersLink[row["user_id"]].add(row["news_id"])
			else:
				self.usersLink[row["user_id"]].add(-row["news_id"])
			#.usersLink[row["user_id"]].append(row["news_id"])
	 
		#sql = " SELECT * FROM `nc_upper` WHERE user_id in ( SELECT upper_user_id WHERE user_id = %d) or user_id = %d
		for row in self.db.getAll("SELECT user_id,upper_user_id from nc_upper"):
			if len(self.leaders) <= row["user_id"]:
				self.leaders.extend([[]] * (row["user_id"] - len(self.leaders) + 1))
			self.leaders[row["user_id"]].append(row["upper_user_id"])
		
		for row in self.db.getAll("SELECT user_id,fans_user_id from nc_fans"):
			if len(self.fans) <= row["user_id"]:
				self.fans.extend([[]] * (row["user_id"] - len(self.fans) + 1))
			self.fans[row["user_id"]].append(row["fans_user_id"])

	def getRecommendationByUid(self,uid):
		candidates = []
		if uid in self.fans:candidates.extend(self.fans[uid])
		if uid in self.leaders:candidates.extend(self.leaders[uid])
		for i in self.leaders[uid]:
			candidates.extend(self.leaders[i])
		candidates = [i for i in set(candidates)]
		similarities = {}
		total = 0;
		for i in range(1,len(self.usersLink)):
			if i != uid: 
				similarity = 1.0 * len(self.usersLink[uid] & self.usersLink[i]) / len(self.usersLink[uid] | self.usersLink[i])
				if len(self.usersLink[uid] | self.usersLink[i]) < 10:
					similarity /= 10
				if similarity > 0 :
					total += 1
					has = self.db.getOne("SELECT count(*) from nc_recommend where user_id = %d and source_user_id = %d " % (uid , i))
					#print has
					if has:
						data = {"recommend_score":similarity}
						self.db.update(data , " user_id = %d and source_user_id = %d " % (uid , i))
					else:
						data = {"user_id" : uid , "source_user_id" : i , "recommend_score" : similarity , "last_modify_time" : time.time()}
						self.db.insert(data)


	def getUsers(self):
		print "print usres"
if __name__ == "__main__":
	recommendation = R()
	for i in range(1,len(recommendation.usersLink)):
		recommendation.getRecommendationByUid(i)
